import ast

import requests

import pandas as pd
import base64
import json
import os
import shutil
import time
import random
from collections import OrderedDict
from urllib.parse import quote_plus
import redis
import requests
from sqlalchemy import create_engine
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from DrissionPage.common import Settings
from DrissionPage.common import Keys
from DrissionPage.common import Actions
import pymysql
from DrissionPage.errors import *

import datetime

from spider_code.mysql_ini import mysql_config_ini, redis_config_ini

"""
https://customer.xiaohongshu.com/api/cas/customer/web/qr-code?service=https:%2F%2Fcreator.xiaohongshu.com&qr_code_id=68c517395516719772176435"""

class DY_XPIDER:
    def __init__(self,user_id):
        self.CO = ChromiumOptions()  ##创建chrome实例
        # self.user_id = self.user_input()  ##用户
        self.user_id = str(user_id)  ##用户

        self.PORT = self.port_input()  ##chrome端口
        self.CO.set_paths(browser_path="browser_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome")  ##chrome启动路径
        self.CO.set_local_port(self.PORT)  ##生成的端口 这里是手动生成
        self.CO.set_user_data_path(os.getcwd() + '/user_info_dir/{}'.format(self.user_id))  ##用户chrome文件夹
        # self.CO.arguments.append('--headless')
        self.ch = ChromiumPage(self.CO)


        self.ch.set.window.max()  ##chrome窗口最大化
        # self.ac = Actions(self.ch)
        # self.fans = self.xhs_user_info_requests()

        self.redis_conn = redis.StrictRedis(host=redis_config_ini()["host"], port=redis_config_ini()["port"],
                                            password=redis_config_ini()["password"], db=redis_config_ini()["database"])

        # self.redis_conn = redis.StrictRedis(host='r-bp1u7oiaxwfpof7014.redis.rds.aliyuncs.com', port=6379,
        #                                     password='GHGOAPSqVaMWZJf6JCT', db=0)


    """根据用户ID查出端口号"""

    def port_fe(self):
        sql = "select spider_user_id,spider_port,spider_login_code from dy_creator_center where spider_user_id='{}'".format(
            self.user_id)
        spider_config = self.pymysql_fetchall(sql)
        port = []
        for i in spider_config:
            port.append(i[1])

        return ''.join(port)

    """自动输入端口号"""

    def port_input(self):

        port1 = random.randint(5000, 9000)

        cc = self.port_jiance()
        while True:
            cc = self.port_jiance()
            if cc == "用户存在":
                # print("当前用户存在")
                port_ = self.port_fe()
                # print(port_)
                return port_
            if cc == "端口不存在":
                # print(port1)
                return port1
            else:
                return self.PORT

    """自动随机生成端口 并进行检测"""

    def port_jiance(self):
        port1 = random.randint(5000, 9000)

        sql = "select spider_user_id,spider_port,spider_login_code from dy_creator_center"
        spider_config = self.pymysql_fetchall(sql)
        port_list = []
        # print(spider_config)
        for i in spider_config:
            port_list.append(i[1])
        user_exists = self.user_state()
        # print(user_exists, '************')
        if user_exists == "用户不存在":
            if port1 not in port_list:
                return "端口不存在"
            else:
                return "端口存在"
        else:
            return '用户存在'

    """查询数据库"""

    def pymysql_fetchall(self, sql):

        con = pymysql.connect(host=mysql_config_ini()["host"], port=mysql_config_ini()["port"], user=mysql_config_ini()["user"],
                              passwd=mysql_config_ini()["password"], db=mysql_config_ini()["database"], charset='utf8')
        # 获取操作数据的对象 cursor
        cursor = con.cursor()
        cursor.execute(sql)
        sql_result = cursor.fetchall()
        # 提交事务
        con.commit()
        # 关闭Cursor
        cursor.close()
        # 关闭链接
        con.close()

        return sql_result

    # def pymysql_fetchall(self, sql):
    #
    #     con = pymysql.connect(host='rm-bp17709mm0o30s13r.mysql.rds.aliyuncs.com', port=3306, user='warehouse',
    #                           passwd='QlciCnfTB9NtLSC', db='data-warehouse', charset='utf8')
    #     # 获取操作数据的对象 cursor
    #     cursor = con.cursor()
    #     cursor.execute(sql)
    #     sql_result = cursor.fetchall()
    #     # 提交事务
    #     con.commit()
    #     # 关闭Cursor
    #     cursor.close()
    #     # 关闭链接
    #     con.close()
    #
    #     return sql_result

    """从数据库判断用户是否存在"""

    def user_state(self):
        sql = "select spider_user_id,spider_port,spider_login_code from dy_creator_center"
        result = self.pymysql_fetchall(sql)
        user_list = []
        for i in result:
            user_list.append(i[0])
        # print(user_list)
        if self.user_id in user_list:
            # print("存在")
            return "用户存在"
        else:
            return "用户不存在"

    """判断用户是否在数据库中 不在为新用户 在的话为老用户"""

    def user_info(self):
        engine2 = self.mysql_config()
        data_frame = pd.DataFrame([{"spider_user_id": str(self.user_id), "spider_port": str(self.PORT)}])
        # print(data_frame)
        # pd.io.sql.to_sql(data_frame, 'xhs_user_info', engine2, schema='live_data',if_exists='append',index=False)
        return data_frame


    # def mysql_config(self):
    #     user = 'live_data'
    #     password = quote_plus('CJMg2tsHg7sj6bo0UTKq0a4T!fPDpJ')
    #     # passwd ='merchantsasd123!@%&'
    #     host = 'rm-bp17r99475xuauk63yo.mysql.rds.aliyuncs.com'
    #     # port1 ='3306'
    #     dbname2 = 'live_data'
    #     engine2 = create_engine(f"mysql+pymysql://{user}:{password}@{host}:3306/{dbname2}?charset=utf8mb4")
    #     return engine2


    def mysql_config(self):
        user = mysql_config_ini()["user"]
        password = quote_plus(mysql_config_ini()["password"])
        # passwd ='merchantsasd123!@%&'
        host = mysql_config_ini()["host"]
        # port1 ='3306'
        dbname2 = mysql_config_ini()["database"]
        engine2 = create_engine(f"mysql+pymysql://{user}:{password}@{host}:3306/{dbname2}?charset=utf8mb4")
        return engine2

    # def mysql_config(self):
    #     user = 'warehouse'
    #     # password = quote_plus('QlciCnfTB9NtLSC')
    #     password = 'QlciCnfTB9NtLSC'
    #     # passwd ='merchantsasd123!@%&'
    #     host = 'rm-bp17709mm0o30s13r.mysql.rds.aliyuncs.com'
    #     # port1 ='3306'
    #     dbname2 = 'data-warehouse'
    #     engine2 = create_engine(f"mysql+pymysql://{user}:{password}@{host}:3306/{dbname2}?charset=utf8mb4")
    #     return engine2

    """修改用户登录状态的mysql"""

    def pymysql_update_dy_user_info(self, sql,):

        con = pymysql.connect(host=mysql_config_ini()["host"], port=mysql_config_ini()["port"], user=mysql_config_ini()["user"],
                              passwd=mysql_config_ini()["password"], db=mysql_config_ini()["database"], charset='utf8')
        # 获取操作数据的对象 cursor
        cursor = con.cursor()
        cursor.execute(sql)
        # sql_result = cursor.fetchall()
        # 提交事务
        con.commit()
        # 关闭Cursor
        cursor.close()
        # 关闭链接
        con.close()

        return "修改成功"



    """登录二维码状态监控"""
    def qrcode_save(self):
        time.sleep(3)
        print("二维码获取中")
        douyin_qrcode_text = self.ch.ele('xpath://*[@id="sub-app"]/div/div[2]/div[3]/div/div[2]/div/div[2]/div[2]/div[1]/img[1]')
        print(douyin_qrcode_text)
        douyin_qrcode_redis = str(douyin_qrcode_text).split("<ChromiumElement img src=")[1].split(">")[0].split('\n')[0]
        img_base = douyin_qrcode_redis.encode("utf-8")
        self.redis_conn.set('douyin_qrcode:{}'.format(self.user_id), img_base)
        print("写入成功")
        self.redis_conn.expire('douyin_qrcode:{}'.format(self.user_id), 180)

    def delete_folder_random(self,random_id):
        try:
            shutil.rmtree(os.getcwd() + "\\user_info_dir\\" + random_id)
            print(f"成功删除文件夹")
        except OSError as e:
            print(f"删除文件夹失败")

    def login_stauts_listen(self):
        time.sleep(3)
        self.ch.listen.start('https://sso.douyin.com/check_qrconnect')

        login_status_list = []
        telephone_num_list = []
        for packet in self.ch.listen.steps():
            # print(packet.url)

            try:
                status_value = str(packet.response.body["data"]["status"])
                if status_value == "1":
                    self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '1')
                    self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id), 300)
                    print("等待扫码中")

                if status_value == "2":
                    self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '2')
                    self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id), 300)
                    print("扫码成功")

                if status_value == "3":
                    self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '3')
                    self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id), 300)
                    print("登录成功")
                    break

                # print("二维码状态",status_value)
                if status_value == '5':
                    self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '5')
                    self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id), 300)
                    print("扫码超时或授权超时")
                    return "扫码超时或授权超时"

            except:
                if packet.response.body["verify_scene_desc"] == "你的登录可能存在风险，为保护账号安全，请进行安全验证":
                    time.sleep(1)
                    self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '6')
                    self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id), 300)
                    print("需要短信验证登录")
                    self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div[1]/div/div[1]/p').click()
                    time.sleep(0.5)
                    #点击获取验证码按钮
                    self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()
                    """验证码手机号"""
                    telephone_num = self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/p[1]/span/span')
                    telephone_num = telephone_num.text
                    print(telephone_num,"*****************")
                    self.redis_conn.set('dy_telephone:{}'.format(self.user_id), '{}'.format(str(telephone_num).replace('*','A')))
                    self.redis_conn.expire('dy_telephone:{}'.format(self.user_id), 300)
                    telephone_num_list.append(telephone_num)
                    cu_time = datetime.datetime.now()
                    while True:
                        value = self.redis_conn.get('dy_message_qrcode:{}'.format(self.user_id))
                        # print(value)
                        if value == None:
                            en_time = datetime.datetime.now()
                            all_time = en_time - cu_time
                            if all_time.seconds == 60 :
                                print(all_time.seconds,"*******")

                                ###点击重新发送按钮
                                time.sleep(1)
                                self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()
                                # self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()
                                # self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '7')
                                # self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id),60)
                                # return "手机验证码超时，请重新授权"
                            if all_time.seconds == 120 :
                                print(all_time.seconds,"*******")

                                time.sleep(1)
                                self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()

                            # if all_time.seconds == 180 :
                            #     time.sleep(1)
                            #     self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()

                            if all_time.seconds == 180 :
                                print(all_time.seconds,"*******")

                                time.sleep(1)
                                self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()
                            if all_time.seconds == 240 :
                                print(all_time.seconds,"*******")

                                time.sleep(1)
                                self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()
                            if all_time.seconds >= 300 :
                                print(all_time.seconds,"*******")
                                time.sleep(1)
                                self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '10')
                                self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id), 300)
                                return "手机验证码超时，请重新授权"

                                # self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p').click()
                            # print("正在获取验证码")
                        else:
                            print("获取到了验证码")
                            print(value)
                            self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[1]/input').input('{}\n'.format(value))
                            break

                    time.sleep(1)
                    # self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[3]/div/div[2]').click()

                    # self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[1]/input').click()
                    #输入验证码
                    # //*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[1]/input
                    ##验证按钮
                    self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[3]/div/div[2]').click()
                    time.sleep(2)
                    try:
                        error_message = self.ch.ele('xpath://*[@id="uc-second-verify"]/div/div/article/div[2]/p[2]')
                        error_message = error_message.text
                        print(error_message)
                        if error_message == '验证码错误，请重新输入':
                            print("验证码错误，请重新输入")
                            self.redis_conn.set('dy_center_qrcode_status:{}'.format(self.user_id), '11')
                            self.redis_conn.expire('dy_center_qrcode_status:{}'.format(self.user_id), 300)
                            return "验证码错误"
                    except:
                        print("往下走")
                        # break
                        # print("往下走")

                # break
                    #//*[@id="uc-second-verify"]/div/div/article/div[3]/div/div[2]
            # print(packet.response.body)
            # print(packet.url)
        time.sleep(2)
        print("走到这这里了&&&&&&&&&&&&&&&")
        if 'creator-micro/home' in self.ch.url:

            return "抖音创作中心用户登录成功"


    def pymysql_update(self, sql,num,user_id):

        con = pymysql.connect(host=mysql_config_ini()["host"], port=mysql_config_ini()["port"], user=mysql_config_ini()["user"],
                              passwd=mysql_config_ini()["password"], db=mysql_config_ini()["database"], charset='utf8')
        # 获取操作数据的对象 cursor
        cursor = con.cursor()
        cursor.execute(sql,(num,user_id))
        sql_result = cursor.fetchall()
        # 提交事务
        con.commit()
        # 关闭Cursor
        cursor.close()
        # 关闭链接
        con.close()

        return sql_result

    """抖音创作者中心用户详情获取"""

    def dy_user_info_detail(self):
        self.ch.refresh()
        "https://creator.douyin.com/aweme/v1/creator/user/info/"
        self.ch.listen.start('https://creator.douyin.com/aweme/v1/creator/user/info')

        user_fans_list = []
        nick_name_list = []
        douyin_unique_id_list = []

        for packet in self.ch.listen.steps(timeout=4):
            user_info = packet.response.body
            douyin_unique_id = user_info["douyin_user_verify_info"]["douyin_unique_id"]
            douyin_unique_nickname = user_info["douyin_user_verify_info"]["nick_name"]
            user_fans = user_info["douyin_user_verify_info"]["follower_count"]
            user_fans_list.append(user_fans)
            nick_name_list.append(douyin_unique_nickname)
            douyin_unique_id_list.append(douyin_unique_id)
            # print(douyin_unique_nickname)
            # print(douyin_unique_id)

            # print(user_info)

        # user_sql = "select douyin_account_id from data_warehouse_douyin_account_data"
        user_sql = "select douyin_unique_id from dy_user_info"
        user_sql_list = self.pymysql_fetchall(user_sql)
        user_list = []
        for i in user_sql_list:
            user_list.append(i[0])
        print(user_list,"*****************************************")
        if douyin_unique_id_list[0] in user_list:
            print("存在存在存在*********")
            print(douyin_unique_id_list[0])
            dy_user_sql = "update dy_user_info set dy_spider_user_id='{}' where douyin_unique_id='{}'".format(self.user_id,douyin_unique_id_list[0])
            self.pymysql_update_dy_user_info(dy_user_sql)
            # dy_user_info_sql = "select douyin_unique_id_id from dy_user_info"
            # dy_user_info_sql_list = self.pymysql_fetchall(dy_user_info_sql)
            # print(dy_user_info_sql_list)

        else:
            curr_time = datetime.datetime.now()

            user_info_json = {"dy_spider_user_id":self.user_id,"nick_name":nick_name_list[0],"douyin_unique_id":douyin_unique_id_list[0],"user_fans":user_fans_list[0]}

            user_info_account_json = {"nickname": nick_name_list[0], "douyin_account_id": douyin_unique_id_list[0],
                                      "douyin_code": douyin_unique_id_list[0], "data_view_capability_status": 1,
                                      "create_time":curr_time,"update_time":curr_time}
            user_info_account_json_frame = pd.DataFrame([user_info_account_json])


            user_info_frame = pd.DataFrame([user_info_json])


            pd.io.sql.to_sql(user_info_frame, 'dy_user_info', self.mysql_config(), schema='data-warehouse',if_exists='append',index=False)
            print("********---数据插入成功---********")
            # pd.io.sql.to_sql(user_info_account_json_frame, 'data_warehouse_douyin_account_data', self.mysql_config(), schema='data-warehouse',if_exists='append',index=False)
        self.ch.close()
        return nick_name_list[0],douyin_unique_id_list[0]

    """获取cookies"""
    def get_cookies(self):
        cookies_str = ''
        for i in self.ch.cookies(as_dict=False, all_domains=False, all_info=True):
            my_ordered_dict = OrderedDict(i)

            # 取出前两个键值对
            first_two_items = list(my_ordered_dict.items())[:2]
            key_value_str = ''
            count_key_value = 0
            for i in first_two_items:
                count_key_value = count_key_value + 1
                if count_key_value == 1:
                    key_value_str = key_value_str + i[1] + '='
                else:
                    key_value_str = key_value_str + i[1]
            cookies_str = cookies_str + key_value_str + ";"
        return cookies_str


        # 打印简化后的数据
        # print(simplified_data)
        return simplified_data

    def loginSuccessWeb(self,nickname,douyin_code,random):
        url = 'https://www.jisonforest.com/prod-api/central-control/douyin/creatorHome/rpa/loginSuccessWebhook'
        data_par = {
             "nickname": nickname,
             "douyin_code": douyin_code,
             "random": random
        }
        data_refer_result = requests.post(url,json=data_par)
        print(data_refer_result,"回调函数")
        return data_refer_result


    def dy_creator_center_spider(self):

        print('用户:',self.user_id, '此次的端口是:',self.PORT)
        # time.sleep(4)
        self.ch.get('https://creator.douyin.com/creator-micro/home')
        # self.ch.get('https://www.baidu.com')
        time.sleep(4)
        user_it_exist = self.user_state()
        data_frame = self.user_info()
        if user_it_exist == "用户不存在":
            data_frame["spider_login_code"] = '0'
            pd.io.sql.to_sql(data_frame, 'dy_creator_center', self.mysql_config(), schema='data-warehouse',
                             if_exists='append', index=False)

        # print("走到这里了")
        login_url_is = self.ch.url
        if login_url_is == "https://creator.douyin.com/":

            """点击接受短信验证按钮  //*[@id="uc-second-verify"]/div/div/article/div[2]/div/div[1]/div/div[1]/p"""
            """点击获取验证码按钮   //*[@id="uc-second-verify"]/div/div/article/div[2]/div/div/div[2]/p"""
            print(self.qrcode_save())
            login_status = self.login_stauts_listen()
            if login_status == "抖音创作中心用户登录成功":
                print(self.user_id, "登录成功了")
                """授权成功，将数据库用户的状态改为1"""
                sql = 'update dy_creator_center set spider_login_code = %s where spider_user_id = %s'
                print(self.pymysql_update(sql, '1',self.user_id))
            if login_status == "扫码超时或授权超时":
                self.ch.close()
                self.delete_folder_random(self.user_id)

                return {"code": "500", "msg": "授权超时或扫码取消或失败"}
            if login_status == "手机验证码超时，请重新授权":
                self.ch.close()
                self.delete_folder_random(self.user_id)
                return {"code": "500", "msg": "手机验证码超时，请重新授权"}

            if login_status == "验证码错误":
                self.ch.close()
                self.delete_folder_random(self.user_id)
                return {"code": "500", "msg": "手机验证码错误，请重新授权"}

        else:

            self.redis_conn.set('dy_center_qrcode:{}'.format(self.user_id), '"no_login"')
            self.redis_conn.expire('dy_center_qrcode:{}'.format(self.user_id), 300)


        time.sleep(5)
        """获取抖音创作中心的用户详情"""
        detail_result = self.dy_user_info_detail()
        print(detail_result)
        nickename = detail_result[0]
        douyin_code = detail_result[1]
        """结果回调函数"""
        print(self.loginSuccessWeb(nickename, douyin_code, self.user_id))
        return {"code":200,"msg":"账号授权成功"}

dy_center = DY_XPIDER(user_id='doy_test_3')
aa = dy_center.dy_creator_center_spider()

##QlciCnfTB9NtLSC

